


/*
    To avoid maintaining two copies of documentation, common docs for the "boot.txt" file are in G-Force's boot.txt file.
*/




#if _VERSION_ != 471
	print( "Warning: the expected version in boot.txt doesn't match the actual version.\n" );
#endif






#include "includes/common.txt"


#define	SS_PREFS_VERSION		471

// WhiteCap specific prefs...
#define		PREF_CONFIG_INTERVAL			'CInt'
#define		PREF_CONFIG_MORPH_DURATION		'CMor'
#define		PREF_CONFIG_TRANSITION_FCN		'CTrn'




// If the prefs file is missing or outdated, set "factory" settings.
if ( GetPref( PREF_PREFS_VERSION ) != SS_PREFS_VERSION ) {

	SetPref( PREF_PREFS_VERSION, SS_PREFS_VERSION );

	SetPref( PREF_FFT_FADE_AWAY, .6 );
	SetPref( PREF_FFT_NUM_BINS, 59 );
	SetPref( PREF_FFT_SMOOTH, .015 );
	SetPref( PREF_RESPONSE_SCALE, 1.0 );
	SetPref( PREF_PREAMP_SCALE, 1.0 );
	SetPref( PREF_FULLSCREEN_DEVICE, SS_HOST_DISPLAY_DEVICE );
	SetPref( PREF_FULLSCREEN_DEPTH, GetRecommendedFullscreenDepth() );
	SetPref( PREF_FULLSCREEN_X, 640 );
	SetPref( PREF_FULLSCREEN_Y, 480 );
	SetPref( PREF_MAX_SIZE_X, 10000 );
	SetPref( PREF_MAX_SIZE_Y, 10000 );
	SetPref( PREF_PIXEL_DOUBLING, false );
	SetPref( PREF_FORCE_MULTIBLT, false );
	SetPref( PREF_BORDERLESS_WINDOW, false );
	SetPref( PREF_FLOATING_WINDOW, false );
	SetPref( PREF_MAX_COVER_ART_X, 220 );
	SetPref( PREF_MAX_COVER_ART_Y, 220 );
	SetPref( PREF_DESIRED_FRAME_RATE, 40 );		// WhiteCap looks best at 30-40 FPS
	SetPref( PREF_LINE_BOOST, 1 );
	SetPref( PREF_TEXT_FONT, GetSystemFontName() );
	SetPref( PREF_TEXT_SIZE, 18 );
	SetPref( PREF_CHECK_FOR_UPDATES, 7 );
	SetPref( PREF_NETWORK_MODE, 1 );


	// By default, ask the plugin host for the sound data to visualize.
	SetPref( PREF_AUDIO_INPUT_SOURCE, SS_HOST_AUDIO_DEVICE );

	SetPref( PREF_TRACK_TEXT_AUTO , true );
	SetPref( PREF_TRACK_TEXT_DURATION, 14 );

	SetPref( PREF_AUDIO_INPUT_SOURCE, 0 );

	// WhiteCap specific prefs...
	SetPref( PREF_CONFIG_INTERVAL, "12 + rnd( 20 )" );
	SetPref( PREF_CONFIG_MORPH_DURATION, "15 + rnd( 10 )" );
	SetPref( PREF_CONFIG_TRANSITION_FCN, "i^2.1" );


	#if ITUNES
		SetPref( PREF_FFT_BIN_START, 8 );
		SetPref( PREF_FFT_BIN_RANGE, 2 );
		//SetPref( PREF_FFT_MAP_FCN, ".6 * atan( .00008 * x ^ 1.8 )" ); 	  	// 08 Nov 03 - ACO
		//SetPref( PREF_FFT_MAP_FCN, ".35 * atan( .00007*(1+.15 * w) * x ^ 2.0 )" ); 	// 11 Nov 03 - ACO (FFde=.6)
		//SetPref( PREF_FFT_MAP_FCN, ".25 * atan( .0007*(1+.15 * w) * x ^ 1.6 )" ); 	// 15 Nov 03 - ACO (FFde=.7)
		//SetPref( PREF_FFT_MAP_FCN, ".26 * atan( .0003*(1+.15 * w) * x ^ 1.7 )" ); 	// 31 Mar 04 - ACO (FFde=.6)
		SetPref( PREF_FFT_MAP_FCN, ".25 * atan( .0005*(1+.15 * w) * x ^ 1.8 )" );	// 4.6.1
	#elif SONIQUE || XMPLAY
		SetPref( PREF_FFT_BIN_START, 32 );
		SetPref( PREF_FFT_BIN_RANGE, 2 );
		SetPref( PREF_FFT_MAP_FCN, ".5 * atan( .014 * ( 1 + .3 * w ) * x ^ 1.5 )" );
	#elif SOUNDJAM || AUDION
		SetPref( PREF_FFT_BIN_START, 4 );
		SetPref( PREF_FFT_BIN_RANGE, 2 );
		SetPref( PREF_FFT_MAP_FCN, ".6 * atan( .00004 * x ^ 1.7 )" );
	#elif WMP
		SetPref( PREF_FFT_BIN_START, 24 );
		SetPref( PREF_FFT_BIN_RANGE, 2 );
		SetPref( PREF_FFT_FADE_AWAY, .5 );
		//SetPref( PREF_FFT_MAP_FCN, "2.4 * atan( ( .0045 * (pos(x-85) + .2 * x ) )^1.5)" );
		SetPref( PREF_FFT_MAP_FCN, ".7 * atan( ( .019 * pos( x - 40 ) + .003 * pos( x - 20 ) ) )" );	// 4.6.1
	#elif JMC
		SetPref( PREF_FFT_BIN_START, 24 );
		SetPref( PREF_FFT_BIN_RANGE, 2 );
		SetPref( PREF_FFT_FADE_AWAY, .5 );
		SetPref( PREF_FFT_MAP_FCN, ".5 * atan(.0003 * ( .5 + w ) * x ^ 1.7 )" );	// 4 Jun 04
	#elif WINAMP
		SetPref( PREF_FFT_BIN_START, 28 );
		SetPref( PREF_FFT_BIN_RANGE, 1 );
		SetPref( PREF_FFT_FADE_AWAY, .45 );
		//SetPref( PREF_FFT_MAP_FCN, ".45 * atan( .004 * x ^ 1.5 )" );
		SetPref( PREF_FFT_MAP_FCN, ".33 * atan( .0015 * x ^ 1.7 )" );			// 15 Nov 03 - ACO
	#elif JETAUDIO || MEDIAMONKEY
		SetPref( PREF_FFT_BIN_START, 14 );
		SetPref( PREF_FFT_BIN_RANGE, 2 );
		SetPref( PREF_FFT_FADE_AWAY, .45 );
		SetPref( PREF_FFT_MAP_FCN, ".33 * atan( .0015 * x ^ 1.7 )" );			// 15 Nov 03 - ACO
	#elif MUSICMATCH
		SetPref( PREF_FFT_BIN_START, 14 );
		SetPref( PREF_FFT_BIN_RANGE, 2 );
		SetPref( PREF_FFT_FADE_AWAY, .45 );
		//SetPref( PREF_FFT_MAP_FCN, ".000020 * ( pos( x-130 ) )^2.1" );		// 15 Nov 03 - ACO
		SetPref( PREF_FFT_MAP_FCN, ".000016 * ( pos( x-130 ) )^2.1" );			// 4.6.1
	#elif EXPORTER || STANDALONE || BAR || SCREENSAVER
		SetPref( PREF_FFT_SMOOTH, 0.007 );
		SetPref( PREF_FFT_FADE_AWAY, .4 );
		SetPref( PREF_FFT_MAP_FCN, ".48 * atan( ( 9 * x * ( 2 + w ) ) ^ 1.5 )"  );
	#endif

	#if STANDALONE || BAR || SCREENSAVER

		// For modes where there's no host, have the plugin try to take sound input from the system.
		SetPref( PREF_AUDIO_INPUT_SOURCE, SS_BEST_VIS_AUDIO_DEVICE );
	#endif

	// See comments in G-Force's boot file.
	WritePrefs();

}


SetVerboseMode( false );


// We need to apply the stored track text font settings to the runtime environment...
SetDefaultFont( GetPrefStr( PREF_TEXT_FONT ), GetPref( PREF_TEXT_SIZE ), SS_UTF8_CHARSET | SS_BOLD  );





#if ! _MACOS9_
	BindEvent( SS_KEY_DOWN_EVENT | SS_SHIFT_KEY_CODE | 'C',	"			\
		if ( GetPref( PREF_CHECK_FOR_UPDATES ) > 0 ) {				\
			SetPref( PREF_CHECK_FOR_UPDATES, 0 );				\
			print( \"Check for updates OFF\n\" ); }				\
		else {									\
			SetPref( PREF_CHECK_FOR_UPDATES, 7 );				\
			print( \"Check for updates ON (set to every 7 days)\n\" );	\
		}"
	);		
#endif







// ESC Key exits fullscreen
BindEvent( SS_KEY_DOWN_EVENT | 27,				"SetFullscreen( false );" );

// RETURN or ENTER enters fullscreen mode
BindEvent( SS_KEY_DOWN_EVENT | '\r',				"SetFullscreen( ! GetFullscreen() );" );
BindEvent( SS_KEY_DOWN_EVENT | 3, 				"SetFullscreen( ! GetFullscreen() );" );
BindEvent( SS_KEY_DOWN_EVENT | SS_SHIFT_KEY_CODE | '\r',	"SetFullscreen( ! GetFullscreen() );" );


BindEvent( SS_KEY_DOWN_EVENT | 'L', 	"printf( \"Current Config: %s\n\", GetCurrentConfig() );" );	


BindEvent( SS_KEY_DOWN_EVENT | 'R',	"printf( \"fps=%f, load=%d, sleep=%d\n\", GetCurrentFPS(), GetCurrentLoad_MS(), GetPriority_MS() );" );


#define _TOGGLE_PIXEL_DOUBLING	 " 	if ( SetPref( PREF_PIXEL_DOUBLING, ! GetPref( PREF_PIXEL_DOUBLING ) ) == ss_NoErr ) {		\
						if ( GetPref( PREF_PIXEL_DOUBLING ) ) {							\
							print( \"Pixel doubling ON\n\" ); }						\
						else {											\
							print( \"Pixel doubling OFF\n\" );						\
						} }											\
					else {												\
						print( \"Pixel doubling is not supported for this media player.\n\" );			\
					}" );

BindEvent( SS_KEY_DOWN_EVENT | SS_SHIFT_KEY_CODE | 'D', _TOGGLE_PIXEL_DOUBLING );


BindEvent( SS_KEY_DOWN_EVENT | 'U', 	"										\
					SetSlideShow( false );								\
					PurgeFileCache();  								\
					SetConfig( GetCurrentConfig() );						\
					print( \"File cache purged, current config recreated.\n\" );"
);


#define _CONFIG_QUICK_MORPH  	1.4
#define _DEFAULT_MORPH		-1

BindEvent( SS_KEY_DOWN_EVENT | '.',	"NextConfig( 1, _CONFIG_QUICK_MORPH, true );" );
BindEvent( SS_KEY_DOWN_EVENT | ',',	"NextConfig( -1, _CONFIG_QUICK_MORPH, true );" );

#define _TURN_SLIDESHOW_ON	"	ShuffleSlideShow(); 						\
					SetSlideShow( true ); 						\
					print( \"Slideshow mode ON\n\" );"


BindEvent( SS_KEY_DOWN_EVENT | 'G', 	_TURN_SLIDESHOW_ON );

BindEvent( SS_KEY_DOWN_EVENT | 'F', 	"SetSlideShow( false );  					\
					print( \"Slideshow mode OFF\n\"  );" );

BindEvent( SS_KEY_DOWN_EVENT | 'M', 	"NextFullscreenResolution(); 					\
					printf( \"New resolution: %dx%dx%d\", GetPref( PREF_FULLSCREEN_X ), GetPref( PREF_FULLSCREEN_Y ), GetPref( PREF_FULLSCREEN_DEPTH )  );		\
					if ( IsFullscreen() ) {						\
						print( \" -- Reenter full screen mode for changes\" );	\
					}								\
					print( \"\n\" );" );


BindEvent( SS_KEY_DOWN_EVENT | 'M' | SS_SHIFT_KEY_CODE, "					\
		NextFullscreenDepth(); 								\
		printf( \"New depth: %s\", GetPref( PREF_FULLSCREEN_DEPTH ) );			\
		if ( GetPref( PREF_FULLSCREEN_DEPTH ) == GetRecommendedFullscreenDepth() ) {	\
			print( \" (Recommended)\" );	}					\
		else {										\
			print( \" (Not recommended)\" );					\
		}										\
		if ( IsFullscreen() ) {								\
			print( \" -- Reenter full screen mode for changes\" );			\
		}										\
		print( \"\n\" );" );



BindEvent( SS_KEY_DOWN_EVENT | 'K' | SS_SHIFT_KEY_CODE, 	"KillRunningScripts();" );

BindEvent( SS_KEY_DOWN_EVENT | '`', 				"Grab();" );

BindEvent( SS_KEY_DOWN_EVENT | 'H', 				"SetConsoleVisible( true );  Run( \"Help\" );" );
BindEvent( SS_KEY_DOWN_EVENT | 'H' | SS_SHIFT_KEY_CODE,		"LaunchHelp();" );

BindEvent( SS_KEY_DOWN_EVENT | '\\',				"SetConsoleVisible( ! GetConsoleVisible() );" );

BindEvent( SS_KEY_DOWN_EVENT | '-',			"SetPref( PREF_RESPONSE_SCALE,	GetPref( PREF_RESPONSE_SCALE ) * .85 );  printf( \"Response scale: %f\n\", GetPref( PREF_RESPONSE_SCALE ) );" );
BindEvent( SS_KEY_DOWN_EVENT | '=',			"SetPref( PREF_RESPONSE_SCALE,	GetPref( PREF_RESPONSE_SCALE ) / .85 );  printf( \"Response scale: %f\n\", GetPref( PREF_RESPONSE_SCALE ) );" );
BindEvent( SS_KEY_DOWN_EVENT | '+',			"SetPref( PREF_RESPONSE_SCALE,	GetPref( PREF_RESPONSE_SCALE ) / .85 );  printf( \"Response scale: %f\n\", GetPref( PREF_RESPONSE_SCALE ) );" );

BindEvent( SS_KEY_DOWN_EVENT | '[',			"SetPref( PREF_PREAMP_SCALE, 	GetPref( PREF_PREAMP_SCALE ) * .85 );  printf( \"Preamp scale: %f\n\", GetPref( PREF_PREAMP_SCALE ) );" );
BindEvent( SS_KEY_DOWN_EVENT | ']',			"SetPref( PREF_PREAMP_SCALE,	GetPref( PREF_PREAMP_SCALE ) / .85 );  printf( \"Preamp scale: %f\n\", GetPref( PREF_PREAMP_SCALE ) );" );

#define _KILL_TRACK_TEXT		"KillOverlay( SS_OVERLAY_ID_TRACK_TEXT );			\
					KillOverlay( SS_OVERLAY_ID_TRACK_COVER_ART );"

#define _START_TRACK_TEXT		"StartTrackOverlay( GetPref( PREF_TRACK_TEXT_DURATION ), 3 );"


BindEvent( SS_TRACK_BEGIN_EVENT, "				\
	if ( GetSlideShow() ) {					\
		NextConfig( 1, _CONFIG_QUICK_MORPH, false );	\
	}							\
	if ( GetPref( PREF_TRACK_TEXT_AUTO ) ) {		\
		"_START_TRACK_TEXT"				\
	}"
);

// This binds code to remove any chance of track info being present after a song is over (ex, we
//     want to get rid of all track text info if a song ends). 
BindEvent( SS_TRACK_END_EVENT, 	_KILL_TRACK_TEXT );		
	
// Now bind a keystroke to code that will kill any active track info and start new track info...
// Recall how the ANSI C/C++ preprocessor concatenates adjacent quote-delimited strings--we take advantage of this below.
BindEvent( SS_KEY_DOWN_EVENT | 'T', _KILL_TRACK_TEXT _START_TRACK_TEXT );




BindEvent( SS_KEY_DOWN_EVENT | 'T' | SS_SHIFT_KEY_CODE, 	"if ( GetPref( PREF_TRACK_TEXT_AUTO ) ) {				\
									SetPref( PREF_TRACK_TEXT_AUTO, 0 );				\
									print( \"Auto track info OFF\r\" );				\
								}									\
								else {									\
									SetPref( PREF_TRACK_TEXT_AUTO, 1 );			 	\
									print( \"Auto track info ON\r\" );				\
								}"
);





BindEvent( SS_KEY_DOWN_EVENT | 'L' | SS_SHIFT_KEY_CODE,	"				\
		SetPref( PREF_LINE_BOOST, ( GetPref( PREF_LINE_BOOST ) + 1 ) % 5 );  	\
		printf( \"Line boost: %i\n\", GetPref( PREF_LINE_BOOST ) );"
);


// This "MENU+" stuff is temporary until I implement an event binding scheme
BindEvent( SS_MENU_EVENT | 1, 	_TURN_SLIDESHOW_ON );
BindEvent( SS_MENU_EVENT | 3, 	"Grab();" );
BindEvent( SS_MENU_EVENT | 5, 	"Run( \"Help\" );" );
BindEvent( SS_MENU_EVENT | 6, 	"LaunchHelp();" );
BindEvent( SS_MENU_EVENT | 8, 	_TOGGLE_PIXEL_DOUBLING );
BindEvent( SS_MENU_EVENT | 10, 	"SetFullscreen( true );" );


// Winamp used ZXCV keys for track navigation, so we can't use those
#if WINAMP
	#define _VERBOSE_KEY	SS_KEY_DOWN_EVENT | '|'
#else
	#define _VERBOSE_KEY	SS_KEY_DOWN_EVENT | 'V'
#endif

BindEvent( _VERBOSE_KEY, 	"SetVerboseMode( ! VerboseModeEnabled() );		\
				if ( VerboseModeEnabled() ) {				\
					print( \"Verbose mode ON\n\" ); }		\
				else {							\
					print( \"Verbose mode OFF\n\" );		\
				}"
);









// When an FFT must be performed, SetFFTParams() specifies the needed parameters (for example, when G-Force or WhiteCap is
//    in stand-alone mode reading line-in audio).  Likewise, a FFT is *not* used (and these parameters are *not* used)  
//    when FFT data is supplied from a host audio player (ex, iTunes, Winamp, WMP). 
// The following are the arguments (in order) of SetFFTParams():
//	float		mFreqLo;		// Freq of the lowest bin (in Hz)
//	float		mFreqHi;		// Freq of the highest bin (in Hz)
//	float		mNumPeriods;		// The number of periods to sample (for a given frequency).
//	float		mMinWindow;		// The minimum number of seconds to sample for a given freq (this value will override the time implied by mNumPeriods for the given freq).
//	float		mMaxWindow;		// The maximum number of seconds to sample for a given freq (this value will override the time implied by mNumPeriods for the given freq).
//	long		mLinearSpacing;		// Non-zero if bin spacing is linear, otherwise spacing is log 2.
SetFFTParams( 120, 4000, 6, .01, .1, false );




#if STANDALONE
BindEvent( SS_KEY_DOWN_EVENT | 'A' | SS_SHIFT_KEY_CODE, "					\
	if ( SetAudioSource( GetPref( PREF_AUDIO_INPUT_SOURCE ) + 1 ) == ss_NoErr ) {		\
		SetPref( PREF_AUDIO_INPUT_SOURCE, GetPref( PREF_AUDIO_INPUT_SOURCE ) + 1 );	\
	}											\
	else {											\
		SetAudioSource( 0 );								\
		SetPref( PREF_AUDIO_INPUT_SOURCE, 0 );						\
	}											\
	printf( \"Audio input: %s\n\", GetAudioSourceDesc() );"
);




// Apply our audio source pref (otherwise, we'll never get audio input).  Keep in mind that
//    this fcn does do anything if we're not in standalone mode.  If we get an error while
//    trying to select a particular audio source, go back, use the default input.
if ( SetAudioSource( GetPref( PREF_AUDIO_INPUT_SOURCE ) ) != ss_NoErr ) {
	print( "Error opening preferred audio input device.\n" );
}
#endif



